package wechat

import (
	"crypto/tls"
	"encoding/pem"
	"errors"
	"fmt"
	"golang.org/x/crypto/pkcs12"
	"os"
	"product/common/validator"
)

// ***********************************************************************************************************************
//  获取支付证书
// ***********************************************************************************************************************

// GetPks12Cert 添加pkcs12证书
// pkcs12FilePath: pkcs12证书文件路径
// password: pkcs12证书密码
func GetPks12Cert(pkcs12FilePath string,
	password string) (tlsConf *tls.Config,
	err error) {
	if !validator.IsEmptyString(pkcs12FilePath) {
		return nil, errors.New("pkcs12FilePath is empty")
	}
	certPem, certKey, err := getPkcs12(pkcs12FilePath, password)
	if err != nil {
		return nil, fmt.Errorf("read pkcs12 file error: %v", err)
	}
	return getTlsConf(certPem, certKey)
}

// GetPemCert 添加pem证书
// certFile: 证书文件
// keyFile: 证书文件名称
func GetPemCert(certFile,
	keyFile any) (tlsConf *tls.Config,
	err error) {
	cert, key, err := getPem(certFile, keyFile)
	if err != nil {
		return nil, err
	}
	return getTlsConf(cert, key)
}

// ***********************************************************************************************************************
// 私有方法
// ***********************************************************************************************************************

// getTlsConf 获取tls配置
func getTlsConf(pem []byte, key []byte) (*tls.Config,
	error) {
	cert, err := tls.X509KeyPair(pem, key)
	if err != nil {
		return nil, fmt.Errorf("convert pkcs12 to pem error: %v", err)
	}
	return &tls.Config{
		Certificates:       []tls.Certificate{cert},
		InsecureSkipVerify: true,
	}, nil
}

// getPkcs12 获取pkcs12证书
func getPkcs12(pkcs12File any,
	password string) (certPem,
	certKey []byte, err error) {
	var pfxData []byte
	if _, ok := pkcs12File.([]byte); ok {
		pfxData = pkcs12File.([]byte)
	} else {
		if pfxData, err = os.ReadFile(pkcs12File.(string)); err != nil {
			return nil, nil,
				fmt.Errorf("read pkcs12 file error: %v", err)
		}
	}
	certBlocks, err := pkcs12.ToPEM(pfxData, password)
	if err != nil {
		return nil, nil,
			fmt.Errorf("convert pkcs12 to pem error: %v", err)
	}
	for _, b := range certBlocks {
		certKey = append(certKey, pem.EncodeToMemory(b)...)
	}
	certPem = certKey
	return
}

// getPem 获取pem证书
func getPem(pemFile,
	pemFileKey any) (certPem, certKey []byte,
	err error) {
	if _, ok := pemFile.([]byte); ok {
		certPem = pemFile.([]byte)
	} else {
		certPem, err = os.ReadFile(pemFile.(string))
	}
	if _, ok := pemFileKey.([]byte); ok {
		certKey = pemFileKey.([]byte)
	} else {
		certKey, err = os.ReadFile(pemFileKey.(string))
	}
	if err != nil {
		return nil, nil,
			fmt.Errorf("read cert file error: %v", err)
	}
	return
}

// ***********************************************************************************************************************
